package com.gqh.weather.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gqh.weather.domain.dto.TaskSchedule;
import com.gqh.weather.domain.entity.*;
import com.gqh.weather.domain.dto.CategoryScoreData;
import com.gqh.weather.domain.enums.XuekeEnum;
import com.gqh.weather.mapper.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @description 任务学校记录管理服务类
 * @author AI
 * @date 2025-09-21
 */
@Slf4j
@Service
public class TaskSchoolRecordService extends ServiceImpl<TaskSchoolRecordMapper, TaskSchoolRecord> {

    private static final ObjectMapper objectMapper = new ObjectMapper();
    
    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private PaperMapper paperMapper;

    @Autowired
    private PcSubtaskMapper pcSubtaskMapper;
    
    @Autowired
    private StudentAnswerMapper studentAnswerMapper;
    
    @Autowired
    private YjStudentAnswerScoreMapper yjStudentAnswerScoreMapper;

    /**
     * 统计学校分数
     *
     * @param createdBy 创建者ID
     * @param taskId 任务ID
     * @param schoolId 学校ID
     * @return 是否成功
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean statisticSchool(Integer createdBy, Integer taskId, Integer schoolId) {
        try {
            log.info("开始统计学校分数，创建者ID: {}, 任务ID: {}, 学校ID: {}", createdBy, taskId, schoolId);
            
            // 创建结果映射，key为分类ID，value为CategoryScoreData列表
            Map<Integer, List<CategoryScoreData>> res = new HashMap<>();
            
            // 学业发展统计
            List<StudentAnswer> xueyeScore = getXueyeScoreList(taskId, schoolId);
            List<CategoryScoreData> xueyeRes = statisticXueyeScore(taskId, xueyeScore);
            res.put(2, xueyeRes);

            // 如果有任何数据，则生成总览并保存
            if (!xueyeScore.isEmpty() ) {
                // 总览统计
                List<CategoryScoreData> overviewRes = statisticOverview(res);
                res.put(0, overviewRes);
                
                // 将结果转换为JSON字符串
                String strRes = objectMapper.writeValueAsString(res);
                
                // 查询是否已存在记录
                LambdaQueryWrapper<TaskSchoolRecord> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(TaskSchoolRecord::getTaskId, taskId)
                       .eq(TaskSchoolRecord::getSchoolId, schoolId);
                TaskSchoolRecord record = getOne(wrapper);
                
                // 如果不存在则创建新记录
                if (record == null) {
                    record = new TaskSchoolRecord();
                    record.setTaskId(taskId);
                    record.setSchoolId(schoolId);
                    record.setCreatedBy(createdBy);
                }
                
                // 设置结果和报告状态
                record.setResult(strRes);
                record.setIfReport(1); // 已生成报告
                
                // 保存记录
                boolean success = saveOrUpdate(record);
                log.info("统计学校分数完成，创建者ID: {}, 任务ID: {}, 学校ID: {}, 结果: {}", createdBy, taskId, schoolId, success);
                return success;
            }
            
            return true;
        } catch (Exception e) {
            log.error("统计学校分数失败，创建者ID: {}, 任务ID: {}, 学校ID: {}", createdBy, taskId, schoolId, e);
            return false;
        }
    }

    /**
     * 获取学业发展分数列表
     *
     * @param taskId 任务ID
     * @param schoolId 学校ID
     * @return 学生答题记录列表
     */
    private List<StudentAnswer> getXueyeScoreList(Integer taskId, Integer schoolId) {
        try {
            // 获取学校的学生列表
            LambdaQueryWrapper<Student> studentWrapper = new LambdaQueryWrapper<>();
            studentWrapper.eq(Student::getSchoolId, schoolId);
            List<Student> students = studentMapper.selectList(studentWrapper);
            
            // 获取学生ID列表
            List<Integer> studentIds = new ArrayList<>();
            for (Student student : students) {
                studentIds.add(student.getId());
            }
            
            if (studentIds.isEmpty()) {
                return new ArrayList<>();
            }
            
            // 获取学业发展相关的试卷类型（pid=2的学科）
            List<Integer> xueyePaperTypes = new ArrayList<>();
            for (XuekeEnum xueke : XuekeEnum.values()) {
                if ("2".equals(xueke.getPid())) {
                    xueyePaperTypes.add(xueke.getValue());
                }
            }
            
            // 获取学生答题记录（学业发展相关的试卷类型）
            return studentAnswerMapper.selectByTaskIdAndPaperTypesAndStudentIds(
                taskId, xueyePaperTypes, studentIds);
        } catch (Exception e) {
            log.error("获取学业发展分数列表失败，任务ID: {}, 学校ID: {}", taskId, schoolId, e);
            return new ArrayList<>();
        }
    }

    /**
     * 学业发展统计
     *
     * @param scoreList 学生答题记录列表
     * @return 分类分数数据列表
     */
    private List<CategoryScoreData> statisticXueyeScore(Integer taskId, List<StudentAnswer> scoreList) {
        List<CategoryScoreData> scoreDatas = new ArrayList<>();
        if (scoreList.isEmpty()) {
            return scoreDatas;
        }

        PcSubtask pcSubtask = pcSubtaskMapper.selectByPid(taskId);

        List<TaskSchedule> taskSchedule = null;
        try {
            taskSchedule = objectMapper.readValue(pcSubtask.getSchedule(), new TypeReference<List<TaskSchedule>>() {});
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }

        Set<String> types = taskSchedule.stream().map(TaskSchedule::getType).collect(Collectors.toSet());

        // 初始化分数数据映射
        Map<Integer, CategoryScoreData> scoreDataMap = new HashMap<>();
        scoreDataMap.put(9999999, createCategoryScoreData(9999999, "总平均分"));

        if (types.contains("200")) {
            scoreDataMap.put(200, createCategoryScoreData(200, "语文"));
        }
        if (types.contains("201")) {
            scoreDataMap.put(201, createCategoryScoreData(201, "数学"));
        }
        if (types.contains("202")) {
            scoreDataMap.put(202, createCategoryScoreData(202, "英语"));
        }
        if (types.contains("203")) {
            scoreDataMap.put(203, createCategoryScoreData(203, "科学"));
        }
        if (types.contains("204")) {
            scoreDataMap.put(204, createCategoryScoreData(204, "道德与法制"));
        }

        // 统计学生和分数
        Map<Integer, Boolean> studentMap = new HashMap<>();
        for (StudentAnswer score : scoreList) {
            if (!studentMap.containsKey(score.getStudentId())) {
                studentMap.put(score.getStudentId(), true);
            }

            CategoryScoreData sd = scoreDataMap.get(score.getPaperType());
            if (sd != null && score.getTotalScore() != null) {

                // 及格线查询
                int passScore = paperMapper.selectPassScoreById(score.getPaperId());

                if (score.getTotalScore() >= passScore) {
                    sd.setP(sd.getP() != null ? sd.getP() + 1 : 1);
                };
//                if (score.getTotalScore() >= 90) {
//                    sd.setE(sd.getE() != null ? sd.getE() + 1 : 1);
//                } else if (score.getTotalScore() >= 80) {
//                    sd.setG(sd.getG() != null ? sd.getG() + 1 : 1);
//                } else if (score.getTotalScore() >= 60) {
//                    sd.setP(sd.getP() != null ? sd.getP() + 1 : 1);
//                } else {
//                    sd.setF(sd.getF() != null ? sd.getF() + 1 : 1);
//                }
                sd.setScore(sd.getScore() != null ? sd.getScore() + score.getTotalScore()
                        : score.getTotalScore());
            }
        }

        // 添加学生总人数
        int studentCount = studentMap.size();
        double totalScore = 0.0;
        for (CategoryScoreData v : scoreDataMap.values()) {
            if (v.getCategoryId() != 9999999 && v.getScore() != null) {
                totalScore += v.getScore();
            }
            v.setStudentNum(studentCount);
        }

        // 计算总平均分
        if (studentCount > 0) {
            double avgTotal = roundPrecision((totalScore / types.size()), 2);
            CategoryScoreData totalAvg = scoreDataMap.get(9999999);
            if (totalAvg != null) {
                totalAvg.setScore(avgTotal);
                if (avgTotal >= 90) {
                    totalAvg.setE(1);
                } else if (avgTotal >= 80) {
                    totalAvg.setG(1);
                } else if (avgTotal >= 60) {
                    totalAvg.setP(1);
                } else {
                    totalAvg.setF(1);
                }
            }
        }

        // 添加到结果列表
        scoreDatas.addAll(scoreDataMap.values());
        return scoreDatas;
    }

    /**
     * 心理健康统计
     *
     * @param scoreList 学生答题记录列表
     * @return 分类分数数据列表
     */
    private List<CategoryScoreData> statisticMental(List<StudentAnswer> scoreList) {
        List<CategoryScoreData> res = new ArrayList<>();
        if (scoreList.isEmpty()) {
            return res;
        }

        // 对题型统计分数
        Map<Integer, CategoryScoreData> categoryMap = new HashMap<>();
        for (StudentAnswer score : scoreList) {
            if (score.getPaperType() != 400) { // 心理健康试卷类型
                continue;
            }

            // 解析分数数据（简化实现）
            // 实际应该解析score.getScoreData()中的JSON数据
            if (score.getScore() != null) {
                // 这里简化处理，假设只有一个题型
                int qtype = 1; // 题型ID
                CategoryScoreData categoryScoreData = categoryMap.get(qtype);
                if (categoryScoreData == null) {
                    categoryScoreData = createCategoryScoreData(qtype, "心理健康题型" + qtype);
                    categoryMap.put(qtype, categoryScoreData);
                }
                categoryScoreData.setScore(categoryScoreData.getScore() != null ? 
                    categoryScoreData.getScore() + score.getScore() : score.getScore());
                categoryScoreData.setStudentNum(categoryScoreData.getStudentNum() != null ? 
                    categoryScoreData.getStudentNum() + 1 : 1);

                // 计算优良率
                double sc = score.getScore();
                if (sc >= 90) {
                    categoryScoreData.setE(categoryScoreData.getE() != null ? 
                        categoryScoreData.getE() + 1 : 1);
                } else if (sc >= 80) {
                    categoryScoreData.setG(categoryScoreData.getG() != null ? 
                        categoryScoreData.getG() + 1 : 1);
                } else if (sc >= 60) {
                    categoryScoreData.setP(categoryScoreData.getP() != null ? 
                        categoryScoreData.getP() + 1 : 1);
                } else {
                    categoryScoreData.setF(categoryScoreData.getF() != null ? 
                        categoryScoreData.getF() + 1 : 1);
                }
            }
        }

        res.addAll(categoryMap.values());
        return res;
    }

    /**
     * 总览统计
     *
     * @param m 分类分数数据映射
     * @return 总览分类分数数据列表
     */
    private List<CategoryScoreData> statisticOverview(Map<Integer, List<CategoryScoreData>> m) {
        List<CategoryScoreData> overviewScore = new ArrayList<>();

        // 分类名称映射（简化实现）
        Map<Integer, String> categoryNameMap = new HashMap<>();
        categoryNameMap.put(2, "学业发展水平");
        categoryNameMap.put(3, "体质健康水平");
        categoryNameMap.put(4, "心理健康水平");
        categoryNameMap.put(5, "艺术素质水平");

        for (Map.Entry<Integer, List<CategoryScoreData>> entry : m.entrySet()) {
            Integer itemId = entry.getKey();
            List<CategoryScoreData> categorys = entry.getValue();

            if (itemId == 2 || itemId == 3 || itemId == 4 || itemId == 5) {
                boolean addOpt = false;
                CategoryScoreData c = new CategoryScoreData();
                c.setCategoryId(itemId);
                c.setCategoryName(categoryNameMap.getOrDefault(itemId, "未知分类"));

                switch (itemId) {
                    case 2: // 学业取总分
                        for (CategoryScoreData category : categorys) {
                            // 假设学科ID范围在200-299之间
                            if (category.getCategoryId() >= 200 && category.getCategoryId() < 300 && 
                                category.getScore() != null) {
                                c.setScore(c.getScore() != null ? c.getScore() + category.getScore() : category.getScore());
                            }
                            if (c.getStudentNum() == null || c.getStudentNum() == 0) {
                                c.setStudentNum(category.getStudentNum());
                            }
                        }
                        addOpt = true;
                        break;
                    case 3:
                    case 5: // 3体质健康 5艺术素质 总分/学生数
                        double totalScore = 0.0;
                        for (CategoryScoreData category : categorys) {
                            // 假设学科ID范围在200-299之间
                            if (category.getCategoryId() >= 200 && category.getCategoryId() < 300 && 
                                category.getScore() != null) {
                                totalScore += category.getScore();
                            }
                            if (c.getStudentNum() == null || c.getStudentNum() == 0) {
                                c.setStudentNum(category.getStudentNum());
                            }
                        }
                        if (c.getStudentNum() != null && c.getStudentNum() > 0) {
                            c.setScore(roundPrecision(totalScore / c.getStudentNum(), 2));
                        }
                        addOpt = true;
                        break;
                    case 4: // 心理健康 总分
                        for (CategoryScoreData category : categorys) {
                            if (category.getScore() != null) {
                                c.setScore(c.getScore() != null ? c.getScore() + category.getScore() : category.getScore());
                            }
                            if (c.getStudentNum() == null || c.getStudentNum() == 0) {
                                c.setStudentNum(category.getStudentNum());
                            }
                        }
                        addOpt = true;
                        break;
                }

                if (addOpt) {
                    overviewScore.add(c);
                }
            }
        }

        return overviewScore;
    }

    /**
     * 体质健康统计（简化实现）
     *
     * @param taskId 任务ID
     * @param schoolId 学校ID
     * @return 分类分数数据列表
     */
    private List<CategoryScoreData> statisticHealthScore(Integer taskId, Integer schoolId) {
        // 简化实现，实际需要根据具体的HealthScore实体类实现
        List<CategoryScoreData> scoreDatas = new ArrayList<>();
        
        CategoryScoreData hc = new CategoryScoreData();
        hc.setCategoryId(3);
        hc.setCategoryName("体质健康水平");
        hc.setStudentNum(0);
        hc.setScore(0.0);
        scoreDatas.add(hc);
        
        return scoreDatas;
    }

    /**
     * 艺术素质统计（简化实现）
     *
     * @param taskId 任务ID
     * @param schoolId 学校ID
     * @return 分类分数数据列表
     */
    private List<CategoryScoreData> statisticArtScore(Integer taskId, Integer schoolId) {
        // 简化实现，实际需要根据具体的ArtScore实体类实现
        List<CategoryScoreData> scoreDatas = new ArrayList<>();
        
        CategoryScoreData sd5 = new CategoryScoreData();
        sd5.setCategoryId(5);
        sd5.setCategoryName("艺术素质水平");
        sd5.setStudentNum(0);
        sd5.setScore(0.0);
        scoreDatas.add(sd5);
        
        return scoreDatas;
    }

    /**
     * 创建分类分数数据对象
     *
     * @param categoryId 分类ID
     * @param categoryName 分类名称
     * @return 分类分数数据对象
     */
    private CategoryScoreData createCategoryScoreData(Integer categoryId, String categoryName) {
        CategoryScoreData data = new CategoryScoreData();
        data.setCategoryId(categoryId);
        data.setCategoryName(categoryName);
        data.setScore(0.0);
        data.setStudentNum(0);
        data.setE(0);
        data.setG(0);
        data.setP(0);
        data.setF(0);
        return data;
    }

    /**
     * 四舍五入精度处理
     *
     * @param value 值
     * @param precision 精度
     * @return 处理后的值
     */
    private double roundPrecision(double value, int precision) {
        double scale = Math.pow(10, precision);
        return Math.round(value * scale) / scale;
    }
}